package com.googlecode.transmutant

import java.util.HashSet
import org.apache.log4j.BasicConfigurator 
import org.apache.log4j.Level 
import org.apache.log4j.LogManager 

public class StepValidator implements Steppable { {
		BasicConfigurator.configure()
		LogManager.rootLogger.level = Level.INFO
	}
	
	def log = LogManager.getLogger(StepValidator.class);
	
	void step(def steps) {
		steps.each {step->
			
			def orderSet = [] as Set
			def orderList = []
			def outSet = [] as Set
			def outList = []
			
			step.class.methods.each {m->
				if (m.isAnnotationPresent(Step.class)){
					def order = m.getAnnotation(Step.class).order()
					orderSet.add(order)
					orderList.add(order)
				}
				if (m.isAnnotationPresent(Out.class)){
					def name = m.getAnnotation(Out.class).name()
					outSet.add(name)
					outList.add(name)
				}
			}
			
			checkForDuplicateAnnotations(step, outSet, outList)
			
			if (orderList.size() != 1 && orderSet.size() < orderList.size()){
				throw new IllegalStateException("@Step methods should have unique order values")
			}
		}
	}
	
	private checkForDuplicateAnnotations(step, outSet, outList) {
		def inSet = [] as Set
		def inList = []
		
		step.class.declaredFields.each {f->
			if (f.isAnnotationPresent(In.class)){
				def name = f.getAnnotation(In.class).name()
				inSet.add(name)
				inList.add(name)
			}
			if (f.isAnnotationPresent(Out.class)){
				def name = f.getAnnotation(Out.class).name()
				outSet.add(name)
				outList.add(name)
			}
		}
		
		if(inSet.size() < inList.size()) {
			log.warn("duplicate @In names found")
		}
		if(outSet.size() < outList.size()) {
			log.warn("duplicate @Out names found")
		}
	}
}
